package pgdgit01;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;

/**
 * Runs a trivial library and its item checkout system by presenting the user
 * with a menu. Used to teach students to use Subversion.
 * @author PGDSWD team, October 2013
 */
public class LibraryCheckout {
    /**
     * Runs the library checkout system.
     * @param args, the array of command line arguments
     * 
     */
    //Array of publications.
    static ArrayList<Publication> publicationsList = new ArrayList<>();
    //Array of library users. 
    static ArrayList<Borrower> borrowersList = new ArrayList<>();
    static Scanner input = new Scanner(System.in);
    public static void main(String[] args) {
        String item;
        populatesPublications();    //adding new publications
        populateBorrowers();        //registering library users 
        do{
            System.out.println("MENU\n\n1. List all library items\n2. Add a new item"
                    + "\n3. Delete an item\n4. Select a borrower\n5. Add a borrower"
                    + "\n6. Delete a borrower\n9. Quit ");
            System.out.println("Enter the number of your menu choice:");
            item = input.next();
            //repeats until item is 1 up to 6 or 9
            while(!item.matches("[1-6 9]")){
                System.out.println("Please, enter the valid number of your menu choice: ");
                item = input.next();
            }
            
            switch(item){

                case "1":
                    displayLibraryItems();
                    System.out.println("Press Enter to return to the menu:");
                    input.nextLine();
                    input.nextLine();
                    break;
                case "2":
                    addNewItem();
                    break;               
                case "3":
                   deleteItem();
                    break;
                case "4" :
                    selectBorrower();
                    break;
                case "5":
                    addBorrower();
                    break;
                case "6":
                    deleteBorrower();
                    break;
            }
        }while(!item.equals("9"));
    }
    //adding new publications
    private static void populatesPublications(){
        publicationsList.add(new Publication(PublicationType.BOOK, "Much Ado About Nothing", "William Aspley",
                                             "1600", "London", "William ShakeSpeare"));
         publicationsList.add(new Publication(PublicationType.JOURNAL, "Journal of Software Engineering: Vol 23, No.3", "Springer Verlag",
                                             "June 2011", "Berlin", "Various"));
          publicationsList.add(new Publication(PublicationType.DVD, "Horatio Hornblower", "BBC",
                                             "2008", "London", "C. S. Forester"));
    }
    
    //registering library users
    private static void populateBorrowers(){
        borrowersList.add(new Borrower("Sethu", "33 Brim str, Summerville", "0737606294", "sethu@gmail.com"));
        borrowersList.add(new Borrower("Nezie", "33 Breeze, Northcrest", "073764444", "nezy@gmail.com"));
        borrowersList.add(new Borrower("Alungile", "44 Reibeek str, Belville", "0737606294", "alu@gmail.com"));
    }
    //prints all library items
    public static void displayLibraryItems(){
        for(int publication = 0; publication < publicationsList.size(); publication++){
            System.out.println(publicationsList.get(publication).getFullDetails());
            System.out.println();
        }
    }
    
    //converting strings to Enum
    private static PublicationType convertToEnum(String type){
        PublicationType publicationType;
        switch(type.toUpperCase()){
            case "BOOK":
                publicationType = PublicationType.BOOK;
                break;
            case "JOURNAL":
                publicationType = PublicationType.JOURNAL;
                break;
            case "DVD":
                publicationType = PublicationType.DVD;
                break;
            case "VIDEO":
                publicationType = PublicationType.VIDEO;
                break;
            case "MAGAZINE":
                publicationType = PublicationType.MAGAZINE;
                break;
            case "NEWSPAPER":
                publicationType = PublicationType.NEWSPAPER;
                break;
            default:
                publicationType = PublicationType.E_BOOK;
        }
        return publicationType;
    }
   
    //deleting items from library
    private static void deleteItem(){
        String itemID;
        displayLibraryItems();
        System.out.print("Enter an item ID to delete: ");
        itemID = input.next();
        while(!itemID.matches("[1-"+ Publication.increment +"]")){
            System.out.println("Enter the valid item ID:");
            itemID = input.next();
        }
        
        int count = 0;
        for(int publication = 0; publication < publicationsList.size(); publication++){
            if(publicationsList.get(publication).getItemId() == Integer.parseInt(itemID)){
                publicationsList.remove(publication);
                count++;
                break;
            }
        }
        if(count == 1){
            System.out.println("The item has been deleted.\n");
        }else{
            System.out.println("The selected item does not exist.\n");
        }
    }
   
    //deleting borrower from library
    private static void deleteBorrower(){
        String itemID;
        for(int publication = 0; publication < borrowersList.size(); publication++){
            System.out.println(borrowersList.get(publication).getFullDetails());
            System.out.println();
        }
        System.out.print("Enter the borrower ID to delete: ");
        itemID = input.next();
        while(!itemID.matches("[1-"+ Borrower.count +"]")){
            System.out.println("Enter the valid borrower ID or 0 to exit:");
            itemID = input.next();
            if(itemID.equals("0")){
                break;
            }
        }
        
        if(!itemID.equals("0")){
            int count = 0;
            for(int publication = 0; publication < borrowersList.size(); publication++){
                if(borrowersList.get(publication).getId().equals(itemID)){
                    borrowersList.remove(publication);
                    count++;
                    break;
                }
            }
            if(count == 1){
                System.out.println("The borrower has been deleted.\n");
            }else{
                System.out.println("The selected borrower does not exist.\n");
            }
        }
        
    }   
  
    //adding a new borrower
    private static void addBorrower(){
        String name, address, telephone, email;
        input.nextLine();
       do{ 
        System.out.println("Please enter your name");
        name = input.nextLine();
       }while(name.equals(""));
       do{
          System.out.println("Please enter your address");
                  
          address = input.nextLine();
        }while(address.equals(""));
       
        System.out.println("Please enter your telephone");
        telephone = input.nextLine();
        while(!telephone.matches("[0-9]{10}")){
            System.out.println("Invalid telephone no: e.g 0725896341");
            System.out.println("Please enter your telephone");
            telephone = input.nextLine();
        }
        do{
            System.out.println("Please enter your email");

            email = input.nextLine();

        }while(!email.matches("[^\\d]([\\w \\$ \\.]{1,})(@)([\\w \\.]{2,})(\\.)([\\w \\.]{2,})"));
            
        borrowersList.add(new Borrower(name, address, telephone, email));
        System.out.println(name + " has been added.");
        
   }
    
    //adding a new item
    private static void addNewItem(){
        String pubType, pubName, publisher, pubDate, pubPlace, authors;
                PublicationType itemType;
                input.nextLine();
                System.out.println("Enter publication type or 9 to go back: ");
                pubType = input.nextLine();
                if(!pubType.equals("9")){
                    //repeats until a user enters one of the available publications
                    String msg = "BOOK, JOURNAL, DVD, VIDEO, MAGAZINE, NEWSPAPER, E_BOOK, EBOOK";
                    while(!pubType.toUpperCase().matches("BOOK|JOURNAL|DVD|VIDEO|MAGAZINE|NEWSPAPER|E_BOOK|EBOOK")){
                        
                        System.out.println("These are available publications Type:\n" + msg);
                        System.out.println("Enter valid publication type:");
                        pubType = input.nextLine();
                        if(pubType.equals("9")){
                            pubType = "9";
                            break;
                        }
                    }
                    if(!pubType.equals("9")){
                        itemType = convertToEnum(pubType);
                        if(!pubType.equals("9")){
                            System.out.println("Enter publication name or 9 to go back: ");
                            pubName = input.nextLine(); 
                            if(!pubName.equals("9")){
                            while(!pubName.matches("[a-zA-Z0-9 ' \\s & ]{2,}")){
                                System.out.println("The name must be atleast 3 charecters long or press 9 to go back");
                                pubName = input.nextLine();
                                if(pubName.equals("9")){
                                    break;
                                }
                            }
                            if(!pubName.equals("9")){
                                System.out.println("Enter publisher or 9 to go back: ");
                                publisher = input.nextLine();
                                if(!publisher.equals("9")){
                                while(!publisher.equals("9") && !publisher.matches("[a-zA-Z0-9 ' \\s &]{2,}")){
                                    System.out.println("The name must be atleast 3 charecters long or press 9 to go back");
                                    publisher = input.nextLine();
                                    if(publisher.equals("9")){
                                        break;
                                    }
                                }
                                
                                if(!publisher.equals("9")){
                                    System.out.println("Enter publication date or 9 to go back: ");
                                    pubDate = input.nextLine();
                                    if(!pubDate.equals("9")){
                                    String month = "(JANUARY|FEBRUARY|MARCH|APRIL|MAY|JUNE|JULY|AUGUST|"
                                                + "SEPTEMBER|OCTOBER|NOVEMBER|DECEMBER)";
                                        String allowedDateFormat = "([0-31]{1,3})([\\s-/])" + month + 
                                        "(/|-|\\s)([1900-2013]{4})|" + month + "(/|-|\\s)([1900-2013]{4})|([0-31]{1,3})"
                                                + "([-/])([0-12]{1,3})(/|-|)([1900-2013]{4})|([1900-2013]{4})";
                                    while(!pubDate.toUpperCase().matches(allowedDateFormat)){
                                        System.out.println("Enter the valid date. The allowed format is: dd/mm/yyyy, month/yyyy or yyyy");
                                        pubDate = input.nextLine();
                                        if(pubDate.equals("9")){
                                            break;
                                        }   
                                    }
                                    
                                    
                                    if(!pubDate.equals("9")){
                                        System.out.println("Enter publication place or 9 to go back: ");
                                        pubPlace = input.nextLine();
                                        if(!pubPlace.equals("9")){
                                        
                                        while(!pubPlace.matches("[a-zA-Z0-8 & ' \\s &]{2,}")){
                                            System.out.println("The name must be atleast 3 charecters long or press 9 to go back");
                                            pubPlace = input.nextLine();
                                            if(pubPlace.equals("9")){
                                                break;
                                            }   
                                        }
                                        if(!pubPlace.equals("9")){
                                            System.out.println("Enter authors or 9 to go back: ");
                                            authors = input.nextLine();
                                            if(!authors.equals("9")){
                                            while(!authors.matches("[a-zA-Z , & ' - \\s]{2,}")){
                                                System.out.println("The name must be atleast 3 charecters long or press 9 to go back");
                                                authors = input.nextLine();
                                                if(authors.equals("9")){
                                                    break;
                                                }   
                                            }
                                            if(!authors.equals("9")){
                                                publicationsList.add(new Publication(itemType,pubName, publisher, pubDate, pubPlace,authors));
                                                System.out.println("New item has been added.\n");
                                                System.out.println("Press Enter to return to the menu:");
                                                input.nextLine();
                                            }}
                                        }
                                    }}
                                }}
                            }}
                        }}
                    }
                }
    }
    
    //lists all the library users
    private static void selectBorrower(){
        String borrowerId;
                List<Publication> borrowedItems = null;
                for(int borrower = 0; borrower < borrowersList.size(); borrower++){
                    System.out.println("ID : "+ borrowersList.get(borrower).getId()
                            + "\n" + borrowersList.get(borrower).getName());
                }
                
                System.out.println("Enter the borrower ID to see full borrower details:");
                borrowerId = input.next();
                while(!borrowerId.matches("[1-"+ Borrower.count +"]")){
                    System.out.println("Enter the valid borrower ID or 0 to cancel:");
                    borrowerId = input.next();
                    if(borrowerId.equals("0")){
                        break;
                    }
                }
                if(!borrowerId.equals("0")){
                    Borrower currentBorrower  = null;
                    for(int borrower = 0; borrower < borrowersList.size(); borrower++){
                        if(borrowerId.equals(borrowersList.get(borrower).getId())){
                            currentBorrower = borrowersList.get(borrower);
                            System.out.println(borrowersList.get(borrower).getFullDetails());
                            borrowedItems = borrowersList.get(borrower).getBorrowedItems();
                            System.out.println("\nItem(s) currently on loan:");
                            if(!borrowedItems.isEmpty()){
                                for(int publication = 0; publication < borrowedItems.size(); publication++){
                                    System.out.println(borrowedItems.get(publication).getFullDetails());
                                    System.out.println("Checkout date: " + currentBorrower.getBorrowedItems().get(publication).getCheckoutDate());
                                    System.out.println("Return date: " + currentBorrower.getBorrowedItems().get(publication).getReturnDate());
                                    System.out.println();
                                }
                            }else{
                               System.out.println("No borrowed items at the moment\n"); 
                            }
                            break;
                        }
                    }
                    if(borrowerId.length() ==0){
                        System.out.println("The borrower has been deleted.");
                    }
                    
                    String choice;
                    String itemID;
                    //Menu for a borrower
                    if(borrowerId.length() != 0){
                    do{
                        System.out.println("1. Lend an item to borrower " +
                            borrowerId + "\n2. Return an item from borrower " + 
                            borrowerId + "\n9. Quit borrowers\n\nEnter the "
                            + "number of your menu choice:");
                        choice = input.next();
                        while(!choice.matches("[1-2 9]")){
                            System.out.println("Enter a valid menu of your choice:");
                            choice = input.next();
                        }
                        
                        switch(choice){
                            case "1":
                                displayLibraryItems();
                                System.out.print("Enter an item ID to land an item: ");
                                itemID = input.next();
                                while(!itemID.matches("[1-"+ Publication.increment +"]")){
                                    System.out.println("Enter the valid item ID or 0 to exit:");
                                    itemID = input.next();
                                    if(itemID.equals("0")){
                                        break;
                                    }
                                }
                                if(!itemID.equals("0")){
                                    int count = 0;
                                    Publication borrowed = null;
                                    //Searching for the item of the given ID
                                    for(int publication = 0; publication < publicationsList.size(); publication++){
                                        if(publicationsList.get(publication).getItemId() == Integer.parseInt(itemID)){
                                          borrowed = publicationsList.get(publication);
                                            count++;
                                            break;
                                        }
                                    }

                                    if(count == 1){
                                        SimpleDateFormat dateForamte = new SimpleDateFormat("dd/MM/yyyy");
                                        Date now = new Date();
                                        String checkOutDate = dateForamte.format(now.getTime() );
                                        String returnDate = dateForamte.format(now.getTime() + 10*24*60*60*1000);
                                        try{
                                            if(!currentBorrower.getBorrowedItems().contains(borrowed)){
                                                currentBorrower.checkoutItem(borrowed, checkOutDate, returnDate);
                                                System.out.println("Thank you. The date to  "
                                                        + "return the publication: " + returnDate);
                                            }else{
                                                System.out.println("The item exist in the list of your borrowed items\n");
                                            }
                                        }catch(NullPointerException e){
                                            System.out.println("The item has been deleted!");
                                        }
                                        
                                    }else{
                                        System.out.println("The selected item does not exist.\n");
                                    }
                                }
                                break;
                            case "2":
                                if(!borrowedItems.isEmpty()){
                                    //Prints borrower's full details.
                                    System.out.println("\nItem(s) currently on loan:");
                                    for(int publication = 0; publication < borrowedItems.size(); publication++){
                                        System.out.println(borrowedItems.get(publication).getFullDetails());
                                        System.out.println("Checkout date: " + currentBorrower.getBorrowedItems().get(publication).getCheckoutDate());
                                        System.out.println("Return date: " + currentBorrower.getBorrowedItems().get(publication).getReturnDate());
                                        System.out.println();
                                    }
                                    
                                    System.out.print("Enter the item ID to return an item:\n");
                                    String returnedItemId = input.next();
                                    //repeats until a borrower enters valid itemID
                                    while(!returnedItemId.matches("[1-" + Publication.increment +"]")){
                                        System.out.println("Enter the valid item ID or 0 to exit:");
                                        returnedItemId = input.next();
                                        if(returnedItemId.equals("0")){
                                            break;
                                        }
                                    }
                                    int count = 0;
                                    if(!returnedItemId.equals("0")){
                                        for(int publication = 0; publication < borrowedItems.size(); publication++){
                                            if(borrowedItems.get(publication).getItemId() == Integer.parseInt(returnedItemId)){
                                                borrowedItems.remove(publication);
                                                count++;
                                                break;
                                            }
                                        }
                                        if(count == 1){
                                            System.out.println("Thank you, the item has been successfully returned.\n");
                                        }else{
                                            System.out.println("The item does not exits in the list of your borrowed items.\n");
                                        }
                                    }
                                }else{
                                   System.out.println("No borrowed items at the moment.\n"); 
                                }
                        }
                    }while(!choice.equals("9"));
                }
         }
    }
}
